﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace FrameWorkSong
{
    public abstract partial class MonoBehaviourSimplify
    {
        #region 消息记录对象池
        class MsgRecord
        {
            //类型私有，不支持new
            private MsgRecord() { }
            //对象池
            static Stack<MsgRecord> mMsgRecordPool = new Stack<MsgRecord>();
            public static MsgRecord Allocate(string msgName, Action<object> onMsgReceived)
            {
                MsgRecord retRecord = null;
                if (mMsgRecordPool.Count>0)
                {
                    retRecord= mMsgRecordPool.Pop();
                }
                else
                {
                    retRecord = new MsgRecord();
                }
                retRecord.Name = msgName;
                retRecord.OnMsgReceived = onMsgReceived;
                return retRecord;
            }
            public void Recycle()
            {
                Name = null;
                OnMsgReceived = null;
                mMsgRecordPool.Push(this);
            }
            public string Name;
            public Action<object> OnMsgReceived;
        }
        #endregion

        #region 消息机制管理
        List<MsgRecord> mMsgRecorder = new List<MsgRecord>();
        /// <summary>
        /// 注册消息
        /// </summary>
        /// <param name="msgName"></param>
        /// <param name="onMsgReceived"></param>
        public void RegisterMsg(string msgName, Action<object> onMsgReceived)
        {
            MsgDisPatcher.Register(msgName, onMsgReceived);
            mMsgRecorder.Add( MsgRecord.Allocate(msgName, onMsgReceived));
        }
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="msgName"></param>
        /// <param name="data"></param>
        public void SendMsg(string msgName, object data)
        {
            MsgDisPatcher.Send(msgName, data);
        }
        /// <summary>
        /// 注销消息
        /// </summary>
        /// <param name="msgName"></param>
        /// <param name="onMsgReceived"></param>
        public void UnRegisterMsg(string msgName, Action<object> onMsgReceived)
        {
            var selectedRecords = mMsgRecorder.FindAll(record => record.Name == msgName && record.OnMsgReceived == onMsgReceived);
            selectedRecords.ForEach(record =>
            {
                MsgDisPatcher.UnRegister(record.Name, record.OnMsgReceived);
                mMsgRecorder.Remove(record);
                record.Recycle();
            });
            selectedRecords.Clear();
        }
        /// <summary>
        /// 注销消息
        /// </summary>
        /// <param name="msgName"></param>
        public void UnRegisterMsg(string msgName)
        {
            var selectedRecords = mMsgRecorder.FindAll(record => record.Name == msgName );
            selectedRecords.ForEach(record =>
            {
                MsgDisPatcher.UnRegister(record.Name);
                mMsgRecorder.Remove(record);
                record.Recycle();
            });
            selectedRecords.Clear();
        }
        /// <summary>
        /// 销毁自动注销
        /// </summary>
        void OnDestroy()
        {
            OnBeforeDestroy();
            foreach (var msgRecord in mMsgRecorder)
            {
                MsgDisPatcher.UnRegister(msgRecord.Name, msgRecord.OnMsgReceived);
                //回收对象池
                msgRecord.Recycle();
            }
            mMsgRecorder.Clear();
        }
        /// <summary>
        /// 用于继承MonoBehaviourSimplify的类，实现OnDestroy()方法
        /// </summary>
        public abstract void OnBeforeDestroy();
        #endregion
    }

    public class MsgDisPatcher 
    {
        #region 消息机制注册表

        static Dictionary<string, Action<object>> mRegisteredMsgs = new Dictionary<string, Action<object>>();
        /// <summary>
        /// 注册消息
        /// </summary>
        /// <param name="msgName"></param>
        /// <param name="onMsgReceived"></param>
        public static void Register(string msgName, Action<object> onMsgReceived)
        {
            if (!mRegisteredMsgs.ContainsKey(msgName))
            {
                //没有注册，加空方法
                mRegisteredMsgs.Add(msgName, _ => { });
            }
            //注册多个方法
            mRegisteredMsgs[msgName] += onMsgReceived;
        }
        /// <summary>
        /// 注销全部消息
        /// </summary>
        /// <param name="msgName"></param>
        public static void UnRegister(string msgName)
        {
            if (mRegisteredMsgs.ContainsKey(msgName))
            {
                mRegisteredMsgs.Remove(msgName);
            }
        }
        /// <summary> 
        /// 注销消息
        /// </summary>
        /// <param name="msgName"></param>
        /// <param name="onMsgReceived"></param>
        public static void UnRegister(string msgName, Action<object> onMsgReceived)
        {
            if (mRegisteredMsgs.ContainsKey(msgName))
            {
                mRegisteredMsgs[msgName] -= onMsgReceived;
            }
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="msgName"></param>
        /// <param name="data"></param>
        public static void Send(string msgName, object data)
        {
            if (mRegisteredMsgs.ContainsKey(msgName))
            {
                mRegisteredMsgs[msgName](data);
            }

        }

        #endregion
    }
}